/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include "Ea_Crc16.h"

#define CRC16_INIT_VALUE  0xFFFF

#define EA_START_SEC_CODE
#include "Ea_MemMap.h"

/*
 * Computes an updated version of the CRC from existing CRC.
 * crc: the previous values of the CRC
 * buf: the data on which to apply the checksum
 * length: the number of bytes of data in 'buf' to be calculated.
 */
unsigned short Ea_Update_Crc16(unsigned short crc, const unsigned char *buf,
                            unsigned int length)
{
    unsigned int i;

    for (i = 0; i < length; i++) {
        crc = (unsigned char) (crc >> 8) | (crc << 8);
        crc ^= buf[i];
        crc ^= (unsigned char) (crc & 0xff) >> 4;
        crc ^= (crc << 8) << 4;
        crc ^= ((crc & 0xff) << 4) << 1;
    }

    return crc;
}

/*
 * Computes a CRC, starting with an initialization value.
 * buf: the data on which to apply the checksum
 * length: the number of bytes of data in 'buf' to be calculated.
 */
unsigned short Ea_Crc16(const unsigned char *buf, unsigned int length)
{
    unsigned short crc = CRC16_INIT_VALUE;
    return Ea_Update_Crc16(crc, buf, length);
}

#define EA_STOP_SEC_CODE
#include "Ea_MemMap.h"

#ifdef __cplusplus
}
#endif
